#ifndef __MATH_UTIL_H__
#define __MATH_UTIL_H__

#include <stdint.h>

/** Macro for getting minimum value. No sideeffects, a and b are evaluated once only. */
#define MATH_MIN(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b;})

/** Macro for getting maximum value. No sideeffects, a and b are evaluated once only. */
#define MATH_MAX(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a > _b ? _a : _b;})

#define MATH_LIMIT_RANGE(value, min, max) \
    ({\
        __typeof__(value) _value = (value);\
        __typeof__(min) _min = (min);\
        __typeof__(max) _max = (max);\
        _value < _min ? _min : (_value > _max ? _max : _value);\
    })

#define ARRAY_SIZE(array)   (sizeof(array) / sizeof(array[0]))
#define ARRAY_LAST(array)   array[ARRAY_SIZE(array) - 1]

#define FLOAT_PARAM(value, precision) (int32_t)(value), (int32_t)(math_get_fraction(value) * 1e##precision##f)

//#define abs(v) {__typeof__(v) _v = v; _v >= 0 ? _v : -_v}

#define FL_FMT(precision)   "%s%d.%0" #precision "d"
#define FL_PARAM(value, precision) (value >= 0 ? "" : "-"), abs((int32_t)(value)), (int32_t)(math_get_fraction(value) * 1e##precision##f)

extern float math_get_fraction(float value);

#endif
